/**********************************************************************\

 Copyright 2012 Diggory Blake

 This file is part of klip-engine

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.

\**********************************************************************/
#pragma once

#include "Box2D/Box2D.h"

#pragma comment(lib, "Box2D.lib")

class kBox2DController;

#include "kcontroller.h"
#include "kmath.h"

class kBox2DController : public kController {
private:
	struct kActorData {
		b2Body* body;
		kMat3x3 localTransform;

		inline kActorData() : body(0), localTransform() {
		}
	};

	kMat3x3 _globalTransform;

	void updateTransform(kActor* actor, const kActorData* data);
protected:
	virtual void onActorAdded(kActor* actor);
	virtual void onActorRemoved(kActor* actor);

public:
	kBox2DController();

	void update();

	void setBody(kActor* actor, b2Body* body);
	void setLocalTransform(kActor* actor, const kMat3x3& transform);
	b2Body* getBody(kActor* actor);
	const kMat3x3& getLocalTransform(kActor* actor);
	inline void setGlobalTransform(const kMat3x3& transform) {
		_globalTransform = transform;
	}
	inline const kMat3x3& getGlobalTransform() {
		return _globalTransform;
	}

	static kMat3x3 convertTransform(const b2Transform& transform);
	static b2Transform convertTransform(const kMat3x3& transform);
	inline static const kVec2& convertVec2(const b2Vec2& vec) {
		return reinterpret_cast<const kVec2&>(vec);
	}
	inline static const b2Vec2& convertVec2(const kVec2& vec) {
		return reinterpret_cast<const b2Vec2&>(vec);
	}
	inline static const kVec3& convertVec3(const b2Vec3& vec) {
		return reinterpret_cast<const kVec3&>(vec);
	}
	inline static const b2Vec3& convertVec3(const kVec3& vec) {
		return reinterpret_cast<const b2Vec3&>(vec);
	}
};
